package com.train.daily.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.train.common.enums.impl.BizExceptionEnums;
import com.train.common.exception.GlobalException;
import com.train.common.resp.CommonResp;
import com.train.common.resp.PageResp;
import com.train.daily.dto.seat.DailyTrainSeatCountDTO;
import com.train.daily.dto.seat.DailyTrainSeatEditChoiceSeatDTO;
import com.train.daily.dto.seat.DailyTrainSeatPageDTO;
import com.train.daily.dto.seat.DailyTrainSeatQueryListDTO;
import com.train.daily.mapper.DailyTrainSeatMapper;
import com.train.daily.po.DailyTrainSeatPO;
import com.train.daily.resp.seat.DailyTrainSeatPageResp;
import com.train.daily.resp.seat.DailyTrainSeatQueryListResp;
import com.train.daily.service.DailyTrainSeatService;
import com.train.openfeign.core.utils.OpenFeignUtils;
import com.train.system.api.TrainSeatApi;
import com.train.system.api.TrainStationApi;
import com.train.system.resp.seat.TrainSeatListResp;
import com.train.system.resp.trainstation.TrainStationResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author baitiaojun
 * @description 针对表【dailyTrainSeat(每日座位)】的数据库操作Service实现
 * @createDate 2025-03-01 23:55:05
 */
@Slf4j
@Service
public class DailyTrainSeatServiceImpl extends ServiceImpl<DailyTrainSeatMapper, DailyTrainSeatPO>
    implements DailyTrainSeatService {

    private final DailyTrainSeatMapper dailyTrainSeatMapper;

    private final TrainSeatApi trainSeatFacade;

    private final TrainStationApi trainStationFacade;

    public DailyTrainSeatServiceImpl(DailyTrainSeatMapper dailyTrainSeatMapper,
                                     @Qualifier("com.train.system.api.TrainSeatApi") TrainSeatApi trainSeatFacade,
                                     @Qualifier("com.train.system.api.TrainStationApi") TrainStationApi trainStationFacade) {
        this.dailyTrainSeatMapper = dailyTrainSeatMapper;
        this.trainSeatFacade = trainSeatFacade;
        this.trainStationFacade = trainStationFacade;
    }

    @Override
    public PageResp<DailyTrainSeatPageResp> pageList(DailyTrainSeatPageDTO dailyTrainSeatPageDTO) {
        return dailyTrainSeatMapper.pageList(dailyTrainSeatPageDTO);
    }

    @Override
    public void remove(Long id) {
        boolean isRemoved = this.removeById(id);
        if (!isRemoved) {
            throw new GlobalException(BizExceptionEnums.EXP_REMOVE_DAILY_TRAIN_SEAT);
        }
    }

    @Override
    public void generateDailySeat(String date, List<String> trainCodes) {
        //查询车次基础数据
        CommonResp trainSeatListResp = trainSeatFacade.getTrainSeatListByTrainCodes(trainCodes);

        //类型转换
        List<TrainSeatListResp> trainSeatList = OpenFeignUtils.getResultList(trainSeatListResp, TrainSeatListResp.class);
        if (CollectionUtil.isEmpty(trainSeatList)) {
            throw new GlobalException(BizExceptionEnums.EXP_TRAIN_SEAT_NOT_EXISTS);
        }

        //查询该车次车站
        CommonResp trainStationResp = trainStationFacade.getTrainStationByCode(trainCodes);

        //转换结果
        List<TrainStationResp> trainStationRespList = OpenFeignUtils.getResultList(trainStationResp, TrainStationResp.class);
        if (CollectionUtil.isEmpty(trainStationRespList)) {
            throw new GlobalException(BizExceptionEnums.EXP_TRAIN_STATION_NOT_EXISTS);
        }

        Map<String, Integer> trainStationRespMap = trainStationRespList.stream()
                .collect(Collectors.toMap(TrainStationResp::getTrainCode, TrainStationResp::getCount));

        //重新添加当天座位
        List<DailyTrainSeatPO> dailyTrainSeatPOS = BeanUtil.copyToList(trainSeatList, DailyTrainSeatPO.class);
        dailyTrainSeatPOS.forEach(dailyTrainPO -> {
            dailyTrainPO.setDate(LocalDate.parse(date));
            //添加车次可售卖数
            Integer sellCount = trainStationRespMap.get(dailyTrainPO.getTrainCode());
            dailyTrainPO.setSell(StrUtil.fillBefore("", '0', sellCount + 1));
        });

        //查询当天座位是否存在
        if (dailyTrainSeatMapper.existsSeatByTrain(LocalDate.parse(date), trainCodes)) {
            //删除当天座位
            boolean isDeleted = dailyTrainSeatMapper.deleteTrains(LocalDate.parse(date), trainCodes);
            if (!isDeleted) {
                throw new GlobalException(BizExceptionEnums.EXP_ADD_DAILY_TRAIN_SEAT);
            }
        }

        boolean isSaved = this.saveBatch(dailyTrainSeatPOS);
        if (!isSaved) {
            throw new GlobalException(BizExceptionEnums.EXP_ADD_DAILY_TRAIN_SEAT);
        }
    }

    @Override
    public List<DailyTrainSeatQueryListResp> queryTrainSeatList(DailyTrainSeatQueryListDTO dto) {
        return dailyTrainSeatMapper.selectTrainSeatList(dto);
    }

    @Override
    public void batchEditDailyTrainSeat(List<DailyTrainSeatEditChoiceSeatDTO> choiceSeatDTOList) {
        for (DailyTrainSeatEditChoiceSeatDTO choiceSeat : choiceSeatDTOList) {
            boolean isEdit = dailyTrainSeatMapper.batchEditDailyTrainSeat(choiceSeat);
            if (!isEdit) {
                throw new GlobalException(BizExceptionEnums.EXP_EDIT_DAILY_TRAIN_TICKET);
            }
        }
    }

    @Override
    public Map<String, DailyTrainSeatCountDTO> countDailyTrainSeat(LocalDate date, List<String> trainCodes) {
        Map<String, DailyTrainSeatCountDTO> trainSeatMap = new HashMap<>();
        for (String trainCode : trainCodes) {
            List<DailyTrainSeatCountDTO> dailyTrainSeatCountDTOS = dailyTrainSeatMapper.countDailyTrainSeat(date, trainCode);
            for (DailyTrainSeatCountDTO dailyTrainSeatCountDTO : dailyTrainSeatCountDTOS) {
                trainSeatMap.put(trainCode + dailyTrainSeatCountDTO.getSeatType(), dailyTrainSeatCountDTO);
            }
        }
        return trainSeatMap;
    }
}




